<!--
 * @Descripttion: 公用表格组件
 * @LastEditors: xzh
 * @LastEditTime: 2024-06-10 15:43:02
-->
<template>
  <!-- <div :style="{ height: '100%' }"> -->
  <div>
    <vxe-table
      :border="propsParam.border != false"
      :show-overflow="propsParam.notShowOverflow != false"
      show-header-overflow
      highlight-hover-row
      ref="tableRef"
      :height="!propsParam.bottomUp ? 'auto' : ''"
      :max-height="propsParam.maxHeight || 0"
      align="left"
      round
      :loading="propsParam.loading"
      :data="propsParam.tableData || []"
      :row-config="{
        isCurrent: true,
        isHover: true,
        keyField: 'id',
        ...(propsParam.rowConfig || {}),
      }"
      :column-config="{ resizable: true, minWidth: 100 }"
      :tree-config="propsParam.treeConfig"
      :mouse-config="propsParam.mouseConfig"
      :edit-config="propsParam.editConfig"
      :edit-rules="propsParam.editRules"
      :keep-source="propsParam.keepSource"
      :scroll-x="{ gt: 20, enabled: true, ...(propsParam.scrollX || {}) }"
      :scroll-y="{ gt: 50, enabled: true, ...(propsParam.scrollY || {}) }"
      :checkbox-config="{
        reserve: true,
        trigger: 'row',
        ...(propsParam.checkboxConfig || {}),
      }"
      :radio-config="{
        reserve: true,
        trigger: 'row',
        ...(propsParam.radioConfig || {}),
      }"
      :span-method="propsParam.spanMethod"
      @scroll="handleScroll"
      @cell-click="handleCellClick"
      @cell-dblclick="handleDblclick"
      @checkbox-change="handleSelectionChange"
      @checkbox-all="handleSelectionChange"
      @resizable-change="handleResizableChange"
    >
      <!-- 多选框--ropsParam.checkbox -->
      <vxe-column v-if="!!propsParam.checkbox" type="checkbox" width="50" />
      <vxe-column
        v-if="!!propsParam.radio && !propsParam.checkbox"
        type="radio"
        width="50"
      />
      <!-- 序号默认居中,开启树形表格居左 -->
      <vxe-column
        v-if="!propsParam.notNeedNumber"
        type="seq"
        :title="$t('table.seq')"
        width="50"
      />
      <!-- 列插槽 -->
      <slot name="vxeColumn" />
      <template #empty>
        <slot name="empty">
          <p>{{ $t("table.empty") }}</p>
        </slot>
      </template>
    </vxe-table>
  </div>
  <!-- 分页 -->
  <vxe-pager
    background
    v-if="isPagination"
    v-model:current-page="(paginationParam.pagination || {}).page"
    v-model:page-size="(paginationParam.pagination || {}).rows"
    :total="(paginationParam.pagination || {}).records"
    :layouts="
      propsParam.pageLayouts || [
        'PrevPage',
        'JumpNumber',
        'NextPage',
        'Sizes',
        'Total',
      ]
    "
    @page-change="handlePageChange"
  />
</template>

<script setup lang="ts">
import { ref, reactive, inject, computed } from "vue";
import { paginationParam_Inf, propsParam_Inf } from "../index.type";
import type { object_Inf } from "@/utils/typings/index.type";
import XEUtils from "xe-utils";
import Dile_Methods from "@/utils/methods";

let propsParam: propsParam_Inf | object_Inf = reactive(
  inject("propsParam") || {}
);
/**
 * @Author: xzh
 * @Descripttion:分页参数
 * @Param:
 */
let paginationParam: paginationParam_Inf | object_Inf = reactive(
  inject("paginationParam") || {}
);
//表格ref
let tableRef = ref<any>(null);

/**
 * @Author: xzh
 * @Descripttion:是否分页
 * @Param:
 * @param {*} computed
 */
let isPagination = computed(() => {
  let { scrollLoading, tableRecords, isPagination } = propsParam;
  //不是滚动加载&&表格数据总数>0
  return !scrollLoading && isPagination != undefined
    ? isPagination
    : tableRecords > 0;
});

/**
 * @Author: xzh
 * @Descripttion:单元格被点击时会触发该事件
 * @Param:
 * @param {*} event 回调参数
 */
let handleCellClick = (event: object_Inf) => {
  let { row } = event;
  let { cellClick = () => {} } = propsParam.emitEvents || {};
  //回调行点击事件
  cellClick(row);
};
/**
 * @Author: xzh
 * @Descripttion:	单元格被双击时会触发该事件
 * @Param:
 * @param {*} event
 */
let handleDblclick = (event: object_Inf) => {
  let { row } = event;
  let { cellDblClick = () => {} } = propsParam.emitEvents || {};
  cellDblClick(row);
};
/**
 * @Author: xzh
 * @Descripttion:手动勾选并且值发生改变时触发的事件
 * @Param:
 * @param {*} event 回调参数
 */
let handleSelectionChange = (event: object_Inf) => {
  let { records } = event;
  handelCheckboxChange(records, event);
};
/**
 * @Author: xzh
 * @Descripttion:多选回调勾选事件
 * @Param:
 * @param {*} rowArr
 */
let handelCheckboxChange = (
  rowArr: Array<object_Inf>,
  event: object_Inf = {}
) => {
  let { emitEvents, checkbox, rowConfig = {} } = propsParam || {},
    { checkboxChange = () => {} } = emitEvents || {};
  //获取已保留选中的行数据(多选)
  let caceRowArr = !!checkbox
    ? Dile_Methods.uniqueArr(
        tableRef.value.getCheckboxReserveRecords().concat(rowArr),
        rowConfig.keyField || "id"
      )
    : rowArr;
  //记录表格已选对象
  propsParam.selectObjArr = caceRowArr;
  //触发回调事件
  checkboxChange(caceRowArr, event);
};
/**
 * @Author: xzh
 * @Descripttion:滚动条加载事件
 * @Param:
 * @param {*} data
 */
let handleScrollLoadData = (data: Array<object_Inf>) => {
  propsParam.tableData = (propsParam.tableData || []).concat(data);
  tableRef.value.loadData(XEUtils.clone(data, true));
};
/**
 * @Author: xzh
 * @Descripttion:表格滚动时会触发该事件
 * @Param:
 * @param {*} event
 */
let handleScroll = async (event: object_Inf) => {
  let { isY, scrollTop, scrollHeight } = event,
    { scrollLoading, loading, emitEvents = {} } = propsParam || {},
    { refreshTable = () => {}, scroll = () => {} } = emitEvents || {};
  //变量windowHeight是可视区的高度
  var windowHeight =
    document.documentElement.clientHeight || document.body.clientHeight;
  //是否滑到底部scrollTop+windowHeight>=scrollHeight
  //开启滚动加载&&Y轴&&滑到至底部&&!加载中->回调表格加载
  !!scrollLoading &&
    !!isY &&
    windowHeight + scrollTop >= scrollHeight &&
    !loading &&
    refreshTable();
  //触发滚动事件
  scroll(event);
};
/**
 * @Author: xzh
 * @Descripttion:分页切换事件
 * @Param:
 * @param {*} event
 */
let handlePageChange = (event: object_Inf) => {
  let { pageChange = () => {} } = paginationParam || {};
  pageChange();
};
/**
 * @Author: xzh
 * @Descripttion:宽拖动发生变化事件
 * @Param:
 * @param {*} event
 */
let handleResizableChange = (event: object_Inf) => {
  let { resizableChange = () => {} } = propsParam.emitEvents || {};
  resizableChange(event);
};

/**
 * @description: 设置选中行
 * @param {*} dataArr 设置的数据
 * @param {*} isSelected 是否选中
 * @return {*}
 * @author: ChenWan
 */
const setCheckboxRow = (
  dataArr: Array<object_Inf>,
  isSelected: boolean = true
) => {
  let { setCheckboxRow, setRadioRow, getCheckboxRecords, getRadioRecord } =
      tableRef.value,
    { radio } = propsParam;
  !!radio ? setRadioRow(dataArr.at(0)) : setCheckboxRow(dataArr, isSelected);
  propsParam.selectObjArr = (
    !!radio ? [getRadioRecord()] : getCheckboxRecords()
  ).filter((x: object_Inf) => !!x);
};

//暴露数据或方法
defineExpose({
  tableRef,
  handleScrollLoadData,
  setCheckboxRow,
  clearCheckboxRow: () => tableRef.value.clearCheckboxRow(),
});
</script>
<style lang="scss" scoped></style>
